package com.cuit.dashboard.system.service.impl;

import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cuit.dashboard.common.exception.GlobalException;
import com.cuit.dashboard.common.util.AddressUtil;
import com.cuit.dashboard.common.util.IpUtil;
import com.cuit.dashboard.common.util.PageUtil;
import com.cuit.dashboard.common.util.Result;
import com.cuit.dashboard.common.vo.WeeklyDataVo;
import com.cuit.dashboard.system.dao.SysLoginLogDao;
import com.cuit.dashboard.system.entity.SysAdminEntity;
import com.cuit.dashboard.system.entity.SysLoginLogEntity;
import com.cuit.dashboard.system.entity.vo.LoginLogVO;
import com.cuit.dashboard.system.service.SysLoginLogService;
import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.OperatingSystem;
import eu.bitwalker.useragentutils.UserAgent;
import org.apache.shiro.SecurityUtils;
import org.omg.CORBA.SystemException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.util.*;

/**
 * @program: zuke
 * @description: 登录日志接口实现类
 * @author: KamTang
 * @create: 2022-04-07 21:57
 **/
@Service
public class SysLoginLogServiceImpl extends ServiceImpl<SysLoginLogDao, SysLoginLogEntity> implements SysLoginLogService {

    /**
     * 添加登入日志
     *
     * @param request
     */
    @Override
    public void addLoginReport(HttpServletRequest request) throws UnsupportedEncodingException {
        this.baseMapper.insert(createLoginLog(request));
    }


    /**
     * 创建登录日志
     *
     * @param request
     * @return
     */
    public static SysLoginLogEntity createLoginLog(HttpServletRequest request) throws UnsupportedEncodingException {
        SysAdminEntity sysAdmin = (SysAdminEntity) SecurityUtils.getSubject().getPrincipal();
        SysLoginLogEntity loginLog = new SysLoginLogEntity();
        loginLog.setUsername(sysAdmin.getUsername());
        loginLog.setIp(IpUtil.getIpAddress(request));
        loginLog.setLocation(AddressUtil.getCityInfo(IpUtil.getIpAddress(request)));
        // 获取客户端操作系统
        UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
        // 获取浏览器
        Browser browser = userAgent.getBrowser();
        // 获取操作系统
        OperatingSystem operatingSystem = userAgent.getOperatingSystem();
        loginLog.setUserSystem(operatingSystem.getName());
        loginLog.setUserBrowser(browser.getName());
        loginLog.setLoginTime(new Date());
        return loginLog;
    }

    /**
     * 删除登入日志
     *
     * @param ids
     */
    @Override
    public void deleteBatch(Long[] ids) throws SystemException {
        for (Long id : ids) {
            SysLoginLogEntity loginLog = this.baseMapper.selectById(id);
            if (loginLog == null) {
                throw new GlobalException("id=" + id + "登入日志不存在", 500);
            }
            this.baseMapper.deleteById(id);
        }
    }

    /**
     * 登入日志列表
     *
     * @param params 传入参数
     * @return
     */
    @Override
    public PageUtil findLoginLogList(Map<String, Object> params) {
        // 获取前端当前页
        long currentPage = Long.parseLong((String) params.get("currentPage"));
        // 每页最多数据数
        long pageSize = Long.parseLong((String) params.get("pageSize"));
        QueryWrapper<SysLoginLogEntity> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("login_time");
        // 获取前端具体参数
        String username = (String) params.get("username");
        String ip = (String) params.get("ip");
        String location = (String) params.get("location");
        if (username != null && !"".equals(username)) {
            wrapper.like("username", "%" + username + "%");
        }
        if (ip != null && !"".equals(ip)) {
            wrapper.like("ip", "%" + ip + "%");
        }
        if (location != null && !"".equals(location)) {
            wrapper.like("location", "%" + location + "%");
        }
        Page<SysLoginLogEntity> logEntityPage = new Page<>(currentPage, pageSize);
        IPage<SysLoginLogEntity> iPage = baseMapper.selectPage(logEntityPage, wrapper);
        return new PageUtil(iPage);
    }


    /**
     * 登入报表
     *
     * @param username
     * @return
     */
    @Override
    public List<Map<String, Object>> loginReport(String username) {
        return this.baseMapper.userLoginReport(username);
    }

    //@Override
    //public Map<String, List<?>> getWeeklyAdminLoginAndUserRegData() {
    //    // 管理员近期一周登录情况
    //    List<WeeklyDataVo> loginData = baseMapper.getWeeklyAdminLoginData();
    //    // 获取周
    //    List<String> weekend = loginData.stream().map(WeeklyDataVo::getWeekend).collect(Collectors.toList());
    //    // 获取管理员近期一周登录详细次数
    //    List<Integer> loginTimes = loginData.stream().map(WeeklyDataVo::getCount).collect(Collectors.toList());
    //    // 用户近一周注册情况
    //    Result regMap = consumerServiceFeign.getWeeklyUserRegData();
    //    // 将对象转换成List
    //    List<WeeklyDataVo> regData = regMap.getData("regData", new TypeReference<List<WeeklyDataVo>>() {
    //    });
    //    // 近期一周用户注册详细情况
    //    List<Integer> regTimes = regData.stream().map(WeeklyDataVo::getCount).collect(Collectors.toList());
    //    // 总注册用户人数
    //    List<Integer> list = new ArrayList<>();
    //    list.add(0, (Integer) regMap.get("userTotal"));
    //    // 存放最后结果
    //    Map<String, List<?>> map = new HashMap<>(5);
    //    // 设置标题
    //    ArrayList<String> titles = new ArrayList<>();
    //    titles.add("用户注册次数");
    //    titles.add("管理员登录次数");
    //    map.put("xAbscissa", weekend);
    //    map.put("redData", regTimes);
    //    map.put("blueData", loginTimes);
    //    map.put("titles", titles);
    //    map.put("userTotal", list);
    //    return map;
    //}


    @Override
    public List<LoginLogVO> getLastLoginInfo(String username) {
        List<LoginLogVO> loginInfo = baseMapper.getLastLoginInfo(username);
        // 第一次登录
        if (loginInfo.size() < 2) {
            return loginInfo;
        } else {
            return new ArrayList<>(Collections.singletonList(loginInfo.get(1)));
        }
    }
}
